import * as express from 'express';
import { Container, injectable, inject } from 'inversify';
import { InversifyExpressServer } from 'inversify-express-utils';
import rootControllerFactory from './controllers/root';
import userControllerFactory from './controllers/userController';
import { llog, lerror } from './util/logger';
import DefaultConfig from './config';
import { createHandyClient, IHandyRedis } from 'handy-redis';
import { loadSwagger } from './util/swagger';
import { bootEvent } from './boot';
import { IUserService, tsIUserService } from './service/api/user';
import { UserServiceImpl } from './service/impl/userService';
import { tsISyncService, ISyncService } from './service/api/sync';
import { SyncService } from './service/impl/syncService';
import { desDecrypt } from './util/tools';

export let container: Container;
export let app: express.Application;
export let Config = DefaultConfig;
export let hredis: IHandyRedis;

export let loadConfig = async function() {
	Config = DefaultConfig;
	try {
		let customConfigPath = './config.dev';
		let CustomConfig = await import(customConfigPath);
		Config = CustomConfig.default;
	} catch (e) {
		llog('no custom config');
	}
	// llog('static', Config.getStaticDirectory());
	// llog('res', Config.getResDirectory());
};

let prepareRedis = () => {
	try {
		let redisCfg = Config.getRedis();
		hredis = createHandyClient({
			host: redisCfg.host,
			port: redisCfg.port,
		});
		hredis.redis.on('error', e => {
			llog('app redis connect fail', e);
		});
		hredis.redis.on('connect', async () => {
			llog('app redis connect !!');
			// let v = await hredis.get('k');
			// llog('redis server', hredis.redis.server_info.redis_version);
		});
	} catch (e) {
		llog('redis connect fail', e);
	}
};

export let startApp = async function() {
	// let testjs = require('../srcjs/udp')();

	// 加载配置
	await loadConfig();
	await prepareRedis();

	let swaggerRouter = await loadSwagger();

	// 创建ioc容器和服务器
	container = new Container();
	bootEvent.emit('iocInit', container);
	const ieServer = new InversifyExpressServer(container);
	ieServer
		.setConfig((app: express.Application) => {
			app.use(swaggerRouter);
		})
		.setErrorConfig((app: express.Application) => {
			app.use((err: any, request: express.Request, response: express.Response, next: express.NextFunction) => {
				lerror('express app error', request.connection.remoteAddress, err.stack);
				// lerror('express error', err.status, err.message);
				response.status(err.status || 500).send(err.message);
			});
		});

	// 所有controller在这里初始化
	rootControllerFactory(container);
	// userControllerFactory(container);

	// 所有服务绑定
	container
		.bind<IUserService>(tsIUserService)
		.to(UserServiceImpl)
		.inSingletonScope();
	container
		.bind<ISyncService>(tsISyncService)
		.to(SyncService)
		.inSingletonScope();

	app = ieServer.build();
	bootEvent.emit('appInit', app);
};

bootEvent.on('appInit', () => {});
